package com.jackrain.nea.shiro.stateful;

import com.jackrain.nea.config.Resources;
import com.jackrain.nea.constants.UserLoginConstants;
import com.jackrain.nea.core.query.QueryException;
import com.jackrain.nea.util.IPUtil;
import com.jackrain.nea.util.ShiroSessionUtil;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.face.User;
import com.jackrain.nea.web.face.impl.UserImpl;
import com.jackrain.nea.web.security.Security4Utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Map;

/**
 * Created by Lucky dog on 2016/7/19.
 */

@Component
public  class MonitorAuthenticator extends ModularRealmAuthenticator {

    private Map<String, Object> definedRealms;

    /**
     * 判断登录类型执行操作
     */
    @Override
    protected AuthenticationInfo doAuthenticate(
            AuthenticationToken authenticationToken)
            throws AuthenticationException {

        assertRealmsConfigured();

        ValueHolder vh = new ValueHolder();
        CustomizedToken token = (CustomizedToken)authenticationToken;
        User user = null;
        try {
            user = Security4Utils.getUser(token.getUsername());
        } catch (QueryException e) {
            e.printStackTrace();
        }

        if(user == null || user.getId() == null){
            vh.put("code",-1);
            vh.put("message", "用户名不正确");
            ShiroSessionUtil.setAttribute("vh",vh);
            throw new UnknownAccountException("No account found for user。。。。");
        }

        //根据用户名称查询此用户ISACTIVE
        if (!((UserImpl)user).isActive()){
            vh.put("code",-1);
            vh.put("message", Resources.getMessage("该用户已作废！"));
            ShiroSessionUtil.setAttribute("vh",vh);
            throw new UnknownAccountException("No account found for user。。。。");
        }

        if(StringUtils.isNotBlank(user.getLoginIPRule()) && !IPUtil.checkLoginIP(token.getHost(),user.getLoginIPRule())){
            vh.put("code",-1);
            vh.put("message", "IP不在用户白名单中");
            ShiroSessionUtil.setAttribute("vh",vh);
            throw new IncorrectCredentialsException("该IP不在登录白名单中");
        }

        if(UserLoginConstants.USER_IS_ENABLE_DENIED.equals(user.getIsEnabled()) || !user.isActive() ){
            vh.put("code",-1);
            vh.put("message", "用户已经被锁定");
            ShiroSessionUtil.setAttribute("vh",vh);
            throw new LockedAccountException("User is locked。。。。");
        }

        Realm realm = null;
        if (user.getPasswordHash() != null && user.getPasswordHash().length() > 0) {
            realm = (Realm) this.definedRealms.get("userRealm");
        }else{
            realm = (Realm) this.definedRealms.get("ldapRealm");
        }

        return this.doSingleRealmAuthentication(realm, authenticationToken);

    }

    @Override
    protected void assertRealmsConfigured() throws IllegalStateException {
        this.definedRealms = this.getDefinedRealms();
        if (CollectionUtils.isEmpty(this.definedRealms)) {
            throw new ShiroException("值传递错误!");
        }
    }

    public Map<String, Object> getDefinedRealms() {
        return this.definedRealms;
    }

    public void setDefinedRealms(Map<String, Object> definedRealms) {
        this.definedRealms = definedRealms;
    }


}